#ifndef NR_CHANNEL_OUTPUT_H
#define NR_CHANNEL_OUTPUT_H

#include "nr_data.h"

class nr_channel_output_delegate 
{
public:
    virtual void on_data(nr_data *data) = 0;
    virtual void on_event(nr_event *evt) = 0;
};

typedef enum nr_channel_state
{
    NR_CHANNEL_STATE_STARTED,
    NR_CHANNEL_STATE_PAUSED,
    NR_CHANNEL_STATE_STOPPED,
} nr_channel_state_t;

class nr_channel_operation
{
public:
    nr_channel_operation() : m_state(NR_CHANNEL_STATE_STOPPED) { }
    
    virtual nr_error_t start() { return NR_ERROR_NONE; }
    virtual nr_error_t pause() { return NR_ERROR_NONE; }
    virtual nr_error_t stop() { return NR_ERROR_NONE; }
    
    nr_channel_state_t state() { return m_state; }

    nr_device_id_t& device_id() { return m_device_id; }

protected:
    nr_channel_state_t m_state;
    nr_device_id_t m_device_id;
};

class nr_channel_operation_delegate
{
public:
    virtual nr_error_t on_starting(nr_channel_operation& operation) { return NR_ERROR_NONE; }
    virtual nr_error_t on_started(nr_channel_operation& operation) { return NR_ERROR_NONE; }

    virtual nr_error_t on_pausing(nr_channel_operation& operation) { return NR_ERROR_NONE; }
    virtual nr_error_t on_paused(nr_channel_operation& operation) { return NR_ERROR_NONE; }

    virtual nr_error_t on_stopping(nr_channel_operation& operation) { return NR_ERROR_NONE; }
    virtual nr_error_t on_stopped(nr_channel_operation& operation) { return NR_ERROR_NONE; }
};

class nr_channel_output : public nr_channel_operation, public nr_object
{
public:
    nr_channel_output(nr_channel_output_delegate& data_delegate, 
        nr_channel_operation_delegate& operation_delegate);
    
    virtual ~nr_channel_output();
    
    void fire_data(nr_data *data);
    void fire_event(nr_event *evt);
    
    virtual nr_error_t start();
    virtual nr_error_t pause();
    virtual nr_error_t stop();
    
    nr_id_t channel_id() { return m_channel_id; }
    nr_device_id_t& device_id() { return m_device_id; }

protected:
    nr_channel_output_delegate& m_data_delegate;
    nr_channel_operation_delegate& m_operation_delegate;
    nr_id_t m_channel_id;
    nr_device_id_t m_device_id;

    static nr_id_t g_output_channel_id;
};

#endif // NR_CHANNEL_OUTPUT_H
